home *** CD-ROM | disk | FTP | other *** search
/ Aminet 44 / Aminet 44 (2001)(GTI - Schatztruhe)[!][Aug 2001].iso / Aminet / comm / mail / YAM23src.lha / Source / YAM_CL.c < prev    next >
C/C++ Source or Header  |  2001-06-08  |  22KB  |  530 lines

  1. /***************************************************************************
  2.  
  3.  YAM - Yet Another Mailer
  4.  Copyright (C) 1995-2000 by Marcel Beck <mbeck@yam.ch>
  5.  Copyright (C) 2000-2001 by YAM Open Source Team
  6.  
  7.  This program is free software; you can redistribute it and/or modify
  8.  it under the terms of the GNU General Public License as published by
  9.  the Free Software Foundation; either version 2 of the License, or
  10.  (at your option) any later version.
  11.  
  12.  This program is distributed in the hope that it will be useful,
  13.  but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.  GNU General Public License for more details.
  16.  
  17.  You should have received a copy of the GNU General Public License
  18.  along with this program; if not, write to the Free Software
  19.  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  20.  
  21.  YAM Official Support Site :  http://www.yam.ch
  22.  YAM OpenSource project    :  http://sourceforge.net/projects/yamos/
  23.  
  24.  $Id: YAM_CL.c,v 1.11.2.2 2001/06/08 14:29:37 laursen Exp $
  25.  
  26. ***************************************************************************/
  27.  
  28. #include "YAM.h"
  29.  
  30. /***************************************************************************
  31.  Private MUI classes
  32. ***************************************************************************/
  33.  
  34. /// Definitions
  35. struct MUI_CustomClass *CL_TextEditor;
  36. struct MUI_CustomClass *CL_BodyChunk;
  37. struct MUI_CustomClass *CL_FolderList;
  38. struct MUI_CustomClass *CL_AddressList;
  39. struct MUI_CustomClass *CL_AttachList;
  40. struct MUI_CustomClass *CL_DDString;
  41. struct MUI_CustomClass *CL_DDList;
  42. struct MUI_CustomClass *CL_MainWin;
  43. struct MUI_CustomClass *CL_PageList;
  44. ///
  45. /// BC_Dispatcher (BodyChunk)
  46. //  Subclass of BodyChunk, can load images from files
  47. ULONG SAVEDS ASM BC_Dispatcher(REG(a0,struct IClass *cl), REG(a2,Object *obj), REG(a1,Msg msg))
  48. {
  49.    struct BC_Data *data;
  50.    struct TagItem *tags, *tag;
  51.    int useold;
  52.  
  53.    switch (msg->MethodID)
  54.    {
  55.       case OM_NEW:
  56.          tags = ((struct opSet *)msg)->ops_AttrList;
  57.          obj = (Object *)DoSuperNew(cl, obj,
  58.             MUIA_FixWidth, 16,
  59.             MUIA_FixHeight, 16,
  60.             MUIA_InnerBottom, 0,
  61.             MUIA_InnerLeft, 0,
  62.             MUIA_InnerRight, 0,
  63.             MUIA_InnerTop, 0,
  64.             TAG_MORE, tags);
  65.          if (obj)
  66.          {
  67.             char fname[SIZE_PATHFILE];
  68.             useold = FALSE;
  69.             *fname = 0;
  70.             data = INST_DATA(cl,obj);
  71.             while (tag = NextTagItem(&tags))
  72.             {
  73.                switch (tag->ti_Tag)
  74.                {
  75.                   case MUIA_Bodychunk_UseOld:
  76.                      if (tag->ti_Data) useold = (BOOL)tag->ti_Data;
  77.                      break;
  78.                   case MUIA_Bodychunk_File:
  79.                      if (tag->ti_Data) stccpy(fname, (char *)tag->ti_Data, SIZE_PATHFILE);
  80.                      break;
  81.                }
  82.             }
  83.             if (*fname)
  84.             {
  85.                if (useold) data->BCD = GetBCImage(fname);
  86.                       else data->BCD = LoadBCImage(fname);
  87.                if (data->BCD)
  88.                {
  89.                   set(obj, MUIA_FixWidth,             data->BCD->Width);
  90.                   set(obj, MUIA_FixHeight,            data->BCD->Height);
  91.                   set(obj, MUIA_Bitmap_Width,         data->BCD->Width);
  92.                   set(obj, MUIA_Bitmap_Height,        data->BCD->Height);
  93.                   set(obj, MUIA_Bitmap_SourceColors,  data->BCD->Colors);
  94.                   set(obj, MUIA_Bodychunk_Depth,      data->BCD->Depth);
  95.                   set(obj, MUIA_Bodychunk_Body,       data->BCD->Body);
  96.                   set(obj, MUIA_Bodychunk_Compression,data->BCD->Compression);
  97.                   set(obj, MUIA_Bodychunk_Masking,    data->BCD->Masking);
  98.                   set(obj, MUIA_UserData,             useold);
  99.                }
  100.             }
  101.          }
  102.          return (ULONG)obj;
  103.       case OM_DISPOSE:
  104.          data = INST_DATA(cl,obj);
  105.          get(obj, MUIA_UserData, &useold);
  106.          if (!useold) FreeBCImage(data->BCD);
  107.          break;
  108.    }
  109.    return DoSuperMethodA(cl, obj, msg);
  110. }
  111. ///
  112. /// WS_Dispatcher (Recipient String)
  113. //  Subclass of Betterstring, handles alias auto-completion, drag&drop from address book
  114. ULONG SAVEDS ASM WS_Dispatcher(REG(a0,struct IClass *cl), REG(a2,Object *obj), REG(a1,Msg msg))
  115. {
  116.    ULONG result = 0;
  117.    UBYTE code;
  118.    struct MUIP_DragQuery *d = (struct MUIP_DragQuery *)msg;
  119.    struct WS_Data *data = (struct WS_Data *)INST_DATA(cl,obj);
  120.    struct MUI_NListtree_TreeNode *active;
  121.    struct MUIP_HandleEvent *hmsg;
  122.    
  123.    switch(msg->MethodID)
  124.    {
  125.       case OM_NEW:
  126.          result = DoSuperNew(cl, obj, StringFrame, MUIA_CycleChain, 1, TAG_MORE, ((struct opSet *)msg)->ops_AttrList);
  127.          break;
  128.       case MUIM_Setup:
  129.          if(DoSuperMethodA(cl, obj, msg))
  130.          {
  131.             data->ehnode.ehn_Priority = 1;
  132.             data->ehnode.ehn_Flags    = 0;
  133.             data->ehnode.ehn_Object   = obj;
  134.             data->ehnode.ehn_Class    = cl;
  135.             data->ehnode.ehn_Events   = IDCMP_RAWKEY;
  136.             result = TRUE;
  137.          }
  138.          break;
  139.       case MUIM_GoActive:
  140.          DoMethod(_win(obj), MUIM_Window_AddEventHandler, &data->ehnode);
  141.          result = DoSuperMethodA(cl, obj, msg);
  142.          break;
  143.       case MUIM_GoInactive:
  144.          DoMethod(_win(obj), MUIM_Window_RemEventHandler, &data->ehnode);
  145.          set(obj, MUIA_BetterString_SelectSize, 0);
  146.          result = DoSuperMethodA(cl, obj, msg);
  147.          break;
  148.       case MUIM_HandleEvent:
  149.          hmsg = (struct MUIP_HandleEvent *)msg;
  150.          if (hmsg->imsg && hmsg->imsg->Class == IDCMP_RAWKEY)
  151.          {
  152.             char *contents, *newcontents, *completed = NULL, *comma;
  153.             int pos, allowmulti;
  154.             if (hmsg->imsg->Code == 95 && (hmsg->imsg->Qualifier & IEQUALIFIER_CONTROL))
  155.             {
  156.                DoSuperMethodA(cl, obj, msg);
  157.                get(obj, MUIA_String_Contents, &contents);
  158.                get(obj, MUIA_UserData, &allowmulti);
  159.                if (completed = WR_ExpandAddresses(-1, contents, FALSE, !allowmulti))
  160.                {
  161.                   setstring(obj, completed);
  162.                   FreeStrBuf(completed);
  163.                }
  164.                result = MUI_EventHandlerRC_Eat;
  165.             }
  166.             else
  167.             {
  168.                if (hmsg->imsg->Code == 65) DoMethod(obj, MUIM_BetterString_ClearSelected);
  169.                code = ConvertKey(hmsg->imsg);
  170.                if ((((code >= 32 && code <= 126) || code >= 160) && !(hmsg->imsg->Qualifier & IEQUALIFIER_RCOMMAND)) || (code && hmsg->imsg->Qualifier & IEQUALIFIER_CONTROL))
  171.                {
  172.                   DoSuperMethodA(cl, obj, msg);
  173.                   get(obj, MUIA_String_Contents, &contents);
  174.                   get(obj, MUIA_String_BufferPos, &pos);
  175.                   if (strlen(contents) > 1)
  176.                   {
  177.                      if (comma = strrchr(contents,','))
  178.                      {
  179.                         while (*++comma == ' ');
  180.                         if (strlen(comma) > 1) completed = AB_CompleteAlias(comma);
  181.                      }
  182.                      else completed = AB_CompleteAlias(contents);
  183.                      if (completed)
  184.                      {
  185.                         newcontents = malloc(strlen(contents)+strlen(completed)+1);
  186.                         strcpy(newcontents, contents);
  187.                         strcpy(&newcontents[pos], completed);
  188.                         SetAttrs(obj, MUIA_String_Contents,newcontents, MUIA_String_BufferPos,pos, MUIA_BetterString_SelectSize,strlen(newcontents)-pos, TAG_DONE);
  189.                         free(newcontents);
  190.                      }
  191.                   }
  192.                   result = MUI_EventHandlerRC_Eat;
  193.                }
  194.             }
  195.          }
  196.          break;
  197.       case MUIM_DragQuery:
  198.          result = MUIV_DragQuery_Refuse;
  199.          if (d->obj == G->MA->GUI.NL_MAILS) result = MUIV_DragQuery_Accept;
  200.          else if (d->obj == G->AB->GUI.LV_ADRESSES)
  201.             if (active = (struct MUI_NListtree_TreeNode *)DoMethod(d->obj, MUIM_NListtree_GetEntry, NULL, MUIV_NListtree_GetEntry_Position_Active, 0))
  202.                if (!(active->tn_Flags & TNF_LIST)) result = MUIV_DragQuery_Accept;
  203.          break;
  204.       case MUIM_DragDrop:
  205.          if (d->obj == G->MA->GUI.NL_MAILS)
  206.          {
  207.             struct Mail *mail;
  208.             DoMethod(d->obj, MUIM_NList_GetEntry, MUIV_NList_GetEntry_Active, &mail);
  209.             if (OUTGOING(mail->Folder->Type)) AB_InsertAddress(obj, "", mail->To.RealName, mail->To.Address);
  210.             else AB_InsertAddress(obj, "", mail->From.RealName, mail->From.Address);
  211.          }
  212.          else if (d->obj == G->AB->GUI.LV_ADRESSES)
  213.          {
  214.             struct MUI_NListtree_TreeNode *active = (struct MUI_NListtree_TreeNode *)DoMethod(d->obj, MUIM_NListtree_GetEntry, NULL, MUIV_NListtree_GetEntry_Position_Active, 0);
  215.             struct ABEntry *addr = (struct ABEntry *)(active->tn_User);
  216.             AB_InsertAddress(obj, addr->Alias, addr->RealName, "");
  217.          }
  218.          break;
  219.       default:
  220.          result = DoSuperMethodA(cl, obj, msg);
  221.          break;
  222.    }
  223.    return result;
  224.  
  225. }
  226. ///
  227. /// WL_Dispatcher (Attachment List)
  228. //  Subclass of List, adds Drag&Drop from message list
  229. ULONG SAVEDS ASM WL_Dispatcher(REG(a0,struct IClass *cl), REG(a2,Object *obj), REG(a1,Msg msg))
  230. {
  231.    struct MUIP_DragQuery *d = (struct MUIP_DragQuery *)msg;
  232.  
  233.    switch (msg->MethodID)
  234.    {
  235.       case OM_NEW:
  236.          return DoSuperNew(cl, obj, TAG_MORE, ((struct opSet *)msg)->ops_AttrList);
  237.       case MUIM_Setup:
  238.          if (!DoSuperMethodA(cl, obj, msg)) return FALSE;
  239.          MUI_RequestIDCMP(obj, IDCMP_MOUSEBUTTONS|IDCMP_RAWKEY);
  240.          return TRUE;
  241.       case MUIM_Cleanup:
  242.          MUI_RequestIDCMP(obj, IDCMP_MOUSEBUTTONS|IDCMP_RAWKEY);
  243.          break;
  244.       case MUIM_DragQuery:
  245.          if (d->obj == G->MA->GUI.NL_MAILS) return MUIV_DragQuery_Accept;
  246.          break;
  247.       case MUIM_DragDrop:
  248.          if (d->obj == G->MA->GUI.NL_MAILS)
  249.          {
  250.             struct Attach attach;
  251.             struct Mail *mail;
  252.             int id = MUIV_NList_NextSelected_Start;
  253.             while (TRUE)
  254.             {
  255.                DoMethod(d->obj, MUIM_NList_NextSelected, &id); if (id == MUIV_NList_NextSelected_End) break;
  256.                DoMethod(d->obj, MUIM_NList_GetEntry, id, &mail);
  257.                clear(&attach, sizeof(struct Attach));
  258.                GetMailFile(attach.FilePath, NULL, mail);
  259.                stccpy(attach.Description, mail->Subject, SIZE_DEFAULT);
  260.                strcpy(attach.ContentType, "message/rfc822");
  261.                attach.Size = mail->Size;
  262.                attach.IsMIME = TRUE;
  263.                DoMethod(obj, MUIM_List_InsertSingle, &attach, MUIV_List_Insert_Bottom);
  264.             }
  265.             return 0;
  266.          }
  267.          break;
  268.    }
  269.    return DoSuperMethodA(cl, obj, msg);
  270. }
  271. ///
  272. /// FL_Dispatcher (Folder List)
  273. //  Subclass of NList, adds Drag&Drop from message list
  274. ULONG SAVEDS ASM FL_Dispatcher(REG(a0,struct IClass *cl), REG(a2,Object *obj), REG(a1,Msg msg))
  275. {
  276.    struct MUIP_DragQuery *dq = (struct MUIP_DragQuery *)msg;
  277.    struct MUIP_NList_DropType *dt = (struct MUIP_NList_DropType *)msg;
  278.    struct Folder *srcfolder, *dstfolder;
  279.    static Object *lastobject = NULL;
  280.    int pos = 0;
  281.  
  282.    switch (msg->MethodID)
  283.    {
  284.       case MUIM_NList_DropType:
  285.          if (lastobject != obj) *(dt->type) = MUIV_NList_DropType_Onto; // else  *(dt->type) = MUIV_NList_DropType_Above;
  286.          break;
  287.       case MUIM_DragQuery:
  288.          lastobject = dq->obj;
  289.          if (dq->obj == obj) break;
  290.          if (dq->obj == G->MA->GUI.NL_MAILS) return MUIV_DragQuery_Accept;
  291.          return MUIV_DragQuery_Refuse;
  292.       case MUIM_DragDrop:
  293.          if (dq->obj == obj) break;
  294.          get(obj, MUIA_NList_DropMark, &pos);
  295.          DoMethod(obj, MUIM_NList_GetEntry, pos, &dstfolder);
  296.          DoMethod(obj, MUIM_NList_GetEntry, MUIV_NList_GetEntry_Active, &srcfolder);
  297.          if (dstfolder->Type != FT_SEPARATOR) MA_MoveCopy(NULL, srcfolder, dstfolder, FALSE);
  298.          return 0;
  299.    }
  300.    return DoSuperMethodA(cl,obj,msg);
  301. }
  302. ///
  303. /// EL_Dispatcher (Member List)
  304. //  Subclass of List, adds Drag&Drop from address book window
  305. ULONG SAVEDS ASM EL_Dispatcher(REG(a0,struct IClass *cl), REG(a2,Object *obj), REG(a1,Msg msg))
  306. {
  307.    struct MUIP_DragQuery *d = (struct MUIP_DragQuery *)msg;
  308.    struct MUI_NListtree_TreeNode *active;
  309.  
  310.    switch (msg->MethodID)
  311.    {
  312.       case MUIM_DragQuery:
  313.          if (d->obj == obj) break;
  314.          if (d->obj == G->AB->GUI.LV_ADRESSES && d->obj != obj)
  315.             if (active = (struct MUI_NListtree_TreeNode *)DoMethod(d->obj, MUIM_NListtree_GetEntry, NULL, MUIV_NListtree_GetEntry_Position_Active, 0))
  316.                if (!((struct ABEntry *)(active->tn_User))->Members) return MUIV_DragQuery_Accept;
  317.          return MUIV_DragQuery_Refuse;
  318.       case MUIM_DragDrop:
  319.          if (d->obj == obj) break;
  320.          if (d->obj == G->AB->GUI.LV_ADRESSES && d->obj != obj)
  321.             if (active = (struct MUI_NListtree_TreeNode *)DoMethod(d->obj, MUIM_NListtree_GetEntry, NULL, MUIV_NListtree_GetEntry_Position_Active, 0))
  322.                if (active->tn_Flags & TNF_LIST) EA_AddMembers(obj, active);
  323.                else EA_AddSingleMember(obj, active);
  324.          return 0;
  325.    }
  326.    return DoSuperMethodA(cl,obj,msg);
  327. }
  328. ///
  329. /// AL_Dispatcher (Address book Listtree)
  330. //  Subclass of Listtree, supports inline images and Drag&Drop from message list
  331. ULONG SAVEDS ASM AL_Dispatcher(REG(a0,struct IClass *cl), REG(a2,Object *obj), REG(a1,Msg msg))
  332. {
  333. // struct AL_Data *data;
  334.    struct MUIP_DragQuery *d = (struct MUIP_DragQuery *)msg;
  335.  
  336.    switch (msg->MethodID)
  337.    {
  338.       case MUIM_DragQuery:
  339.             {
  340.          if (d->obj == G->MA->GUI.NL_MAILS) return MUIV_DragQuery_Accept;
  341.  
  342.             }
  343.       break;
  344.  
  345.       case MUIM_DragDrop:
  346.             {
  347.                if (d->obj == G->MA->GUI.NL_MAILS)
  348.         {
  349.             struct Mail **mlist = MA_CreateMarkedList(d->obj);
  350.           if (mlist) { MA_GetAddress(mlist); free(mlist); }
  351.         }
  352.         }
  353.       break;
  354.    }
  355.  
  356.    return DoSuperMethodA(cl,obj,msg);
  357. }
  358. ///
  359. /// MW_Dispatcher (Main Window)
  360. //  Subclass of Windows, used to dispose subwindows on exit
  361. struct MUIP_MainWindow_CloseWindow { ULONG MethodID; APTR Window; };
  362. ULONG SAVEDS ASM MW_Dispatcher(REG(a0,struct IClass *cl), REG(a2,Object *obj), REG(a1,Msg msg))
  363. {
  364.    if (msg->MethodID == MUIM_MainWindow_CloseWindow)
  365.    {
  366.       APTR app, win = ((struct MUIP_MainWindow_CloseWindow *)msg)->Window;
  367.       set(win, MUIA_Window_Open, FALSE);
  368.       get(win, MUIA_ApplicationObject, &app);
  369.       DoMethod(app, OM_REMMEMBER, win);
  370.       MUI_DisposeObject(win);
  371.    }
  372.    else return DoSuperMethodA(cl, obj, (Msg)msg);
  373.  
  374.    return 0;
  375. }
  376. ///
  377. /// TE_Dispatcher (Text Editor)
  378. //  Subclass of Texteditor, adds error requester, Drag&Drop capabilities and multi-color support
  379. ULONG SAVEDS ASM TE_Dispatcher(REG(a0,struct IClass *cl), REG(a2,Object *obj), REG(a1,struct MUIP_TextEditor_HandleError *msg))
  380. {
  381.    switch (msg->MethodID)
  382.    {
  383.       case MUIM_DragQuery:
  384.       {
  385.          struct MUIP_DragDrop *drop_msg = (struct MUIP_DragDrop *)msg;
  386.          return (ULONG)(drop_msg->obj == G->AB->GUI.LV_ADRESSES);
  387.       }
  388.       case MUIM_DragDrop:
  389.       {
  390.          struct MUIP_DragDrop *drop_msg = (struct MUIP_DragDrop *)msg;
  391.          if (drop_msg->obj == G->AB->GUI.LV_ADRESSES)
  392.          {
  393.             struct MUI_NListtree_TreeNode *tn;
  394.             if (tn = (struct MUI_NListtree_TreeNode *)DoMethod(drop_msg->obj, MUIM_NListtree_GetEntry, MUIV_NListtree_GetEntry_ListNode_Active, MUIV_NListtree_GetEntry_Position_Active, 0))
  395.             {
  396.                struct ABEntry *ab = (struct ABEntry *)(tn->tn_User);
  397.                if (ab->Type != AET_GROUP)
  398.                {
  399.                   char *adr = AllocStrBuf(SIZE_DEFAULT);
  400.                   WR_ResolveName(-1, ab->Alias, &adr, FALSE);
  401.                   DoMethod(obj, MUIM_TextEditor_InsertText, adr, MUIV_TextEditor_InsertText_Cursor);
  402.                   FreeStrBuf(adr);
  403.                }
  404.             }
  405.          }
  406.          break;
  407.       }
  408.       case MUIM_TextEditor_HandleError:
  409.       {
  410.          char *errortxt = NULL;
  411.          switch (msg->errorcode)
  412.          {
  413.             case Error_ClipboardIsEmpty:  errortxt = GetStr(MSG_CL_ErrorEmptyCB); break;
  414.             case Error_ClipboardIsNotFTXT:errortxt = GetStr(MSG_CL_ErrorNotFTXT); break;
  415.             case Error_NoAreaMarked:      errortxt = GetStr(MSG_CL_ErrorNoArea); break;
  416.             case Error_NothingToRedo:     errortxt = GetStr(MSG_CL_ErrorNoRedo); break;
  417.             case Error_NothingToUndo:     errortxt = GetStr(MSG_CL_ErrorNoUndo); break;
  418.             case Error_NotEnoughUndoMem:  errortxt = GetStr(MSG_CL_ErrorNoUndoMem); break;
  419.          }
  420.          if (errortxt) MUI_Request(_app(obj), _win(obj), 0L, NULL, GetStr(MSG_OkayReq), errortxt);
  421.          break;
  422.       }
  423.       case MUIM_Show:
  424.       {
  425.          G->EdColMap[6] = MUI_ObtainPen(muiRenderInfo(obj), &C->ColoredText, 0);
  426.          G->EdColMap[7] = MUI_ObtainPen(muiRenderInfo(obj), &C->Color2ndLevel, 0);
  427.          break;
  428.       }
  429.       case MUIM_Hide:
  430.       {
  431.          if (G->EdColMap[6] >= 0) MUI_ReleasePen(muiRenderInfo(obj), G->EdColMap[6]);
  432.          if (G->EdColMap[7] >= 0) MUI_ReleasePen(muiRenderInfo(obj), G->EdColMap[7]);
  433.          break;
  434.       }
  435.    }
  436.    return DoSuperMethodA(cl, obj, (Msg)msg);
  437. }
  438. ///
  439. /// PL_Dispatcher (Config Window Page List)
  440. //  Subclass of List, adds small images to configuration menu
  441. ULONG SAVEDS ASM PL_Dispatcher(REG(a0,struct IClass *cl), REG(a2,Object *obj), REG(a1,Msg msg))
  442. {
  443.    extern UBYTE PL_IconBody[MAXCPAGES][240];
  444.    const ULONG PL_Colors[24] = {
  445.       0x95959595,0x95959595,0x95959595, 0x00000000,0x00000000,0x00000000,
  446.       0xffffffff,0xffffffff,0xffffffff, 0x3b3b3b3b,0x67676767,0xa2a2a2a2,
  447.       0x7b7b7b7b,0x7b7b7b7b,0x7b7b7b7b, 0xafafafaf,0xafafafaf,0xafafafaf,
  448.       0xaaaaaaaa,0x90909090,0x7c7c7c7c, 0xffffffff,0xa9a9a9a9,0x97979797 };
  449.    struct PL_Data *data;
  450.    int i;
  451.  
  452.    switch (msg->MethodID)
  453.    {
  454.       case OM_NEW:
  455.          obj = (Object *)DoSuperNew(cl, obj, TAG_MORE, ((struct opSet *)msg)->ops_AttrList);
  456.          if (obj)
  457.          {
  458.         struct PL_Data *data = INST_DATA(cl,obj);
  459.         InitHook(&data->DisplayHook, CO_PL_DspFunc, data);
  460.             set(obj, MUIA_List_DisplayHook, &data->DisplayHook);
  461.          }
  462.          return (ULONG)obj;
  463.       case MUIM_Setup:
  464.          if (!DoSuperMethodA(cl, obj, msg)) return FALSE;
  465.          data = INST_DATA(cl, obj);
  466.          for (i = 0; i < MAXCPAGES; i++)
  467.          {
  468.             data->Object[i] = BodychunkObject,
  469.                MUIA_FixWidth             , 23,
  470.                MUIA_FixHeight            , 15,
  471.                MUIA_Bitmap_Width         , 23,
  472.                MUIA_Bitmap_Height        , 15,
  473.                MUIA_Bitmap_SourceColors  , PL_Colors,
  474.                MUIA_Bodychunk_Depth      , 3,
  475.                MUIA_Bodychunk_Body       , PL_IconBody[i],
  476.                MUIA_Bodychunk_Compression, 1,
  477.                MUIA_Bodychunk_Masking    , 2,
  478.                MUIA_Bitmap_Transparent   , 0,
  479.             End;
  480.             data->Image[i] = (APTR)DoMethod(obj, MUIM_List_CreateImage, data->Object[i], 0);
  481.          }
  482.          MUI_RequestIDCMP(obj, IDCMP_MOUSEBUTTONS|IDCMP_RAWKEY);
  483.          return TRUE;
  484.       case MUIM_Cleanup:
  485.          data = INST_DATA(cl, obj);
  486.          MUI_RequestIDCMP(obj, IDCMP_MOUSEBUTTONS|IDCMP_RAWKEY);
  487.          for (i = 0; i < MAXCPAGES; i++)
  488.          {
  489.             DoMethod(obj, MUIM_List_DeleteImage, data->Image[i]);
  490.             if (data->Object[i]) MUI_DisposeObject(data->Object[i]);
  491.          }
  492.    }
  493.    return DoSuperMethodA(cl, obj, msg);
  494. }
  495. ///
  496.  
  497. /// ExitClasses
  498. //  Remove custom MUI classes
  499. void ExitClasses(void)
  500. {
  501.    if (CL_PageList   ) MUI_DeleteCustomClass(CL_PageList   );
  502.    if (CL_MainWin    ) MUI_DeleteCustomClass(CL_MainWin    );
  503.    if (CL_TextEditor ) MUI_DeleteCustomClass(CL_TextEditor );
  504.    if (CL_BodyChunk  ) MUI_DeleteCustomClass(CL_BodyChunk  );
  505.    if (CL_FolderList ) MUI_DeleteCustomClass(CL_FolderList );
  506.    if (CL_AddressList) MUI_DeleteCustomClass(CL_AddressList);
  507.    if (CL_DDString   ) MUI_DeleteCustomClass(CL_DDString   );
  508.    if (CL_DDList     ) MUI_DeleteCustomClass(CL_DDList     );
  509.    if (CL_AttachList ) MUI_DeleteCustomClass(CL_AttachList );
  510. }
  511. ///
  512. /// InitClasses
  513. //  Initialize custom MUI classes
  514. BOOL InitClasses(void)
  515. {
  516.     CL_AttachList  = MUI_CreateCustomClass(NULL, MUIC_NList        , NULL, sizeof(struct DumData), ENTRY(WL_Dispatcher));
  517.     CL_DDList      = MUI_CreateCustomClass(NULL, MUIC_List         , NULL, sizeof(struct DumData), ENTRY(EL_Dispatcher));
  518.     CL_DDString    = MUI_CreateCustomClass(NULL, MUIC_BetterString , NULL, sizeof(struct WS_Data), ENTRY(WS_Dispatcher));
  519.     CL_AddressList = MUI_CreateCustomClass(NULL, MUIC_NListtree    , NULL, sizeof(struct AL_Data), ENTRY(AL_Dispatcher));
  520.     CL_FolderList  = MUI_CreateCustomClass(NULL, MUIC_NList        , NULL, sizeof(struct DumData), ENTRY(FL_Dispatcher));
  521.     CL_BodyChunk   = MUI_CreateCustomClass(NULL, MUIC_Bodychunk    , NULL, sizeof(struct BC_Data), ENTRY(BC_Dispatcher));
  522.     CL_TextEditor  = MUI_CreateCustomClass(NULL, MUIC_TextEditor   , NULL, sizeof(struct DumData), ENTRY(TE_Dispatcher));
  523.     CL_MainWin     = MUI_CreateCustomClass(NULL, MUIC_Window       , NULL, sizeof(struct DumData), ENTRY(MW_Dispatcher));
  524.     CL_PageList    = MUI_CreateCustomClass(NULL, MUIC_List         , NULL, sizeof(struct PL_Data), ENTRY(PL_Dispatcher));
  525.  
  526.     return (BOOL)(CL_AttachList && CL_DDList && CL_DDString && CL_AddressList && CL_FolderList && CL_BodyChunk &&
  527.                 CL_TextEditor && CL_MainWin && CL_PageList);
  528. }
  529. ///
  530.